#ifndef BASE_MUTEX_H
#define BASE_MUTEX_H

#include <pthread.h>

class Mutex {
 public:
  Mutex();
  ~Mutex();
  void Lock();
  void Unlock();
  // Read Write
  void ReadLock();
  void ReadUnlock();
  void WriteLock();
  void WriteUnlock();
  int num_readers() {return num_readers_; }
  int num_writers() {return num_writers_; }

 private:
  pthread_mutex_t mutex_;
  pthread_cond_t read_cond_;
  pthread_cond_t write_cond_;
  int num_readers_;
  int num_writers_; 
  int num_writers_waiting_;
};

class MutexLock {
 public:
  MutexLock(Mutex* mutex);
  ~MutexLock();
 private:
  Mutex* mutex_;
};

class ReadLock {
 public:
  ReadLock(Mutex* mutex);
  ~ReadLock();
  void Release();

 private:
  Mutex* mutex_;
};

class WriteLock {
 public:
  WriteLock(Mutex* mutex);
  ~WriteLock();
  void Release();

 private:
  Mutex* mutex_;
};

#endif
